package com.example.chatty.screens.conversation

import android.util.Log
import androidx.compose.animation.*
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.InsertPhoto
import androidx.compose.material.icons.outlined.Mood
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.focusTarget
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.chatty.R
import com.example.chatty.logic.utils.FunctionalityNotAvailablePopup
import com.example.chatty.ui.theme.chattyColors

enum class InputSelector {
    NONE,
    MAP,
    EMOJI,
    PHONE,
    PICTURE
}

enum class EmojiStickerSelector {
    EMOJI,
    STICKER
}

@Preview
@Composable
fun UserInputPreview() {
    UserInput(onMessageSent = {})
}

@Composable
fun UserInput(
    onMessageSent: (String) -> Unit,
    resetScroll: () -> Unit = {},
    modifier: Modifier = Modifier
) {
    var currentInputSelector by rememberSaveable {
        mutableStateOf(InputSelector.NONE)
    }
    LaunchedEffect(key1 = currentInputSelector, block = {
        Log.d("zlf", "SelectorExpanded: $currentInputSelector")
    })

    val dismissKeyboard = { currentInputSelector = InputSelector.NONE }
    if (currentInputSelector != InputSelector.NONE) {
        BackHandler {
            dismissKeyboard()
        }
    }
    var textState by remember {
        mutableStateOf(TextFieldValue())
    }
    var textFieldFocusState by remember {
        mutableStateOf(false)
    }

    Surface(shadowElevation = 2.dp) {
        Column(modifier = modifier) {
            Row(Modifier.fillMaxWidth()) {
                UserInputText(
                    modifier = Modifier.weight(1.0f),
                    textFieldValue = textState,
                    onTextChanged = {
                        textState = it
                    },
                    onMessageSent = {
                        onMessageSent(textState.text)
                        textState = TextFieldValue()
                        resetScroll()
                        dismissKeyboard()
                    },
                    onTextFieldFocused = { focused ->
                        if (focused) {
                            currentInputSelector = InputSelector.NONE
                            resetScroll()
                        }
                        textFieldFocusState = focused
                    },
                    keyboardType = KeyboardType.Text,
                    keyboardShown = currentInputSelector == InputSelector.NONE && textFieldFocusState,
                    focusState = textFieldFocusState
                )
                UserInputSelector(
                    currentInputSelector = currentInputSelector,
                    onSelectorChange = {
                        currentInputSelector = it
                    },
                )
            }
            SelectorExpanded(
                currentInputSelector,
                onTextAdded = { textState = textState.addText(it) })


        }
    }
}

fun TextFieldValue.addText(newString: String): TextFieldValue {
    val newText = this.text.replaceRange(
        startIndex = this.selection.start,
        endIndex = this.selection.end,
        replacement = newString
    )
//   val newSelection = TextRange(start = newText.length, end = newText.length)
    return this.copy(text = newText)
}


@Composable
private fun SelectorExpanded(currentInputSelector: InputSelector, onTextAdded: (String) -> Unit) {
    if (currentInputSelector == InputSelector.NONE) return
    val requester = FocusRequester()
    SideEffect {
        if (currentInputSelector == InputSelector.EMOJI) {
            requester.requestFocus()
        }
    }

    Surface(shadowElevation = 8.dp) {
        when (currentInputSelector) {
            InputSelector.EMOJI -> {
                EmojiSelector(onTextAdded, requester)
            }
            InputSelector.PICTURE -> {
                FunctionalityNotAvailablePanel()
            }
            else -> {
                throw NotImplementedError()
            }
        }
    }
}

@Composable
fun FunctionalityNotAvailablePanel() {
    AnimatedVisibility(visibleState = remember {
        MutableTransitionState(false).apply { this.targetState = true }
    }, enter = expandHorizontally() + fadeIn(), exit = shrinkHorizontally() + fadeOut()) {

        Column(
            modifier = Modifier
                .height(320.dp)
                .fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                text = stringResource(id = R.string.not_available),
                style = MaterialTheme.typography.titleSmall
            )
            Text(
                modifier = Modifier.paddingFrom(FirstBaseline, before = 10.dp),
                text = stringResource(id = R.string.not_available_subtitle),
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurface
            )
        }
    }
}

@Composable
fun EmojiSelector(onTextAdded: (String) -> Unit, focusRequester: FocusRequester) {
    var selected by remember {
        mutableStateOf(EmojiStickerSelector.EMOJI)
    }
    val a11yLabel = stringResource(id = R.string.emoji_selector_desc)

    Column(
        modifier = Modifier
            .focusRequester(focusRequester)
            .focusTarget()
            .semantics { contentDescription = a11yLabel }
    ) {
        Row(
            Modifier
                .fillMaxWidth()
                .padding(horizontal = 8.dp)
        ) {
            ExtendedSelectorInnerButton(
                text = stringResource(id = R.string.emojis_label),
                onClick = { selected = EmojiStickerSelector.EMOJI },
                selected = true,
                modifier = Modifier.weight(1f)
            )
            ExtendedSelectorInnerButton(
                text = stringResource(id = R.string.stickers_label),
                onClick = { selected = EmojiStickerSelector.STICKER },
                selected = true,
                modifier = Modifier.weight(1f)
            )
        }
        Row(Modifier.verticalScroll(rememberScrollState())) {
            EmojiTable(onTextAdded = onTextAdded, Modifier.padding(8.dp))
        }
    }
    if (selected == EmojiStickerSelector.STICKER) {
        NotAvailablePopup(onDismissed = { selected = EmojiStickerSelector.EMOJI })
    }
}

@Composable
fun ExtendedSelectorInnerButton(
    text: String,
    onClick: () -> Unit,
    selected: Boolean,
    modifier: Modifier
) {
    val colors = ButtonDefaults.buttonColors(
        contentColor = MaterialTheme.chattyColors.conversationHintText,
        disabledContentColor = MaterialTheme.chattyColors.conversationHintText,
        containerColor = MaterialTheme.chattyColors.backgroundColor,
        disabledContainerColor = Color.White
    )

    TextButton(
        onClick = onClick,
        modifier = modifier
            .padding(8.dp)
            .height(36.dp),
        enabled = selected,
        contentPadding = PaddingValues(0.dp),
        colors = colors,
        shape = RoundedCornerShape(30.dp)
    ) {
        Text(text = text, style = MaterialTheme.typography.titleSmall)

    }


}

@Composable
private fun NotAvailablePopup(onDismissed: () -> Unit) {
    FunctionalityNotAvailablePopup(onDismissed)
}


@Composable
private fun UserInputSelector(
    currentInputSelector: InputSelector,
    onSelectorChange: (InputSelector) -> Unit,
    modifier: Modifier = Modifier
) {
    Row(
        modifier = modifier
            .height(72.dp)
            .wrapContentHeight()
            .padding(horizontal = 10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        InputSelectedButton(
            selected = currentInputSelector == InputSelector.EMOJI,
            onClick = {
                onSelectorChange(InputSelector.EMOJI)
            },
            icon = Icons.Outlined.Mood,
            description = stringResource(id = R.string.emoji_selector_bt_desc)
        )
        InputSelectedButton(
            selected = currentInputSelector == InputSelector.PICTURE,
            onClick = {
                onSelectorChange(InputSelector.PICTURE)
            },
            icon = Icons.Outlined.InsertPhoto,
            description = stringResource(id = R.string.attach_photo_desc)
        )
    }
}

@Composable
private fun InputSelectedButton(
    selected: Boolean,
    onClick: () -> Unit,
    icon: ImageVector,
    description: String
) {
    val backgroundModifier = if (selected) {
        Modifier.background(
            color = MaterialTheme.chattyColors.conversationInputSelector,
            shape = RoundedCornerShape(14.dp)
        )
    } else {
        Modifier
    }
    IconButton(onClick = { onClick() }, modifier = backgroundModifier) {
        val tint = if (selected) {
            MaterialTheme.chattyColors.conversationInputSelectorSelected
        } else {
            MaterialTheme.chattyColors.conversationInputSelector
        }
        Icon(icon, contentDescription = description, tint = tint, modifier = Modifier.padding(4.dp))
    }
}


val KeyboardShownKey = SemanticsPropertyKey<Boolean>("KeyboardShownKey")
var SemanticsPropertyReceiver.keyboardShownProperty by KeyboardShownKey

@Composable
fun UserInputText(
    modifier: Modifier = Modifier,
    keyboardType: KeyboardType = KeyboardType.Text,
    onTextChanged: (TextFieldValue) -> Unit,
    textFieldValue: TextFieldValue,
    keyboardShown: Boolean,
    onTextFieldFocused: (Boolean) -> Unit,
    focusState: Boolean,
    onMessageSent: () -> Unit,

    ) {
    Surface(
        modifier = modifier
            .fillMaxWidth()
            .height(68.dp)
            .semantics {
                this.keyboardShownProperty = keyboardShown
            }
            .padding(start = 32.dp, end = 6.dp, top = 16.dp, bottom = 16.dp)
            .shadow(
                elevation = 1.dp,
                shape = RoundedCornerShape(30.dp)
            )
    ) {
        Box(
            modifier = Modifier
                .background(MaterialTheme.chattyColors.backgroundColor)
        ) {

            var lastFocusState by remember {
                mutableStateOf(false)
            }
            BasicTextField(
                value = textFieldValue, onValueChange = { onTextChanged(it) }, modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 32.dp)
                    .align(Alignment.CenterStart)
                    .onFocusChanged { state ->
                        if (lastFocusState != state.isFocused) {
                            onTextFieldFocused(state.isFocused)
                        }
                        lastFocusState = state.isFocused
                    },
                keyboardOptions = KeyboardOptions(
                    keyboardType = keyboardType,
                    imeAction = ImeAction.Send
                ),
                keyboardActions = KeyboardActions(
                    onSend = { onMessageSent() }
                ),
                maxLines = 1,
                cursorBrush = SolidColor(LocalContentColor.current),
                textStyle = LocalTextStyle.current.copy(LocalContentColor.current)
            )
            if (textFieldValue.text.isEmpty() && !lastFocusState) {
                Text(
                    modifier = Modifier
                        .align(Alignment.CenterStart)
                        .padding(start = 32.dp),
                    text = stringResource(id = R.string.textfield_hint),
                    style = MaterialTheme.typography.bodyMedium.copy(
                        color = MaterialTheme.chattyColors.conversationHintText
                    )
                )
            }
        }
    }
}

val EMOJI_COLUMS = 9

@Composable
fun EmojiTable(onTextAdded: (String) -> Unit, modifier: Modifier = Modifier) {
    Column(Modifier.fillMaxWidth()) {
        repeat(4) { x ->
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
                repeat(EMOJI_COLUMS) { y ->
                    val emoji = emojis[x * EMOJI_COLUMS + y]
                    Text(
                        text = emoji,
                        modifier = Modifier
                            .clickable { onTextAdded(emoji) }
                            .sizeIn(minWidth = 42.dp, minHeight = 42.dp)
                            .padding(8.dp),
                        style = LocalTextStyle.current.copy(
                            fontSize = 18.sp,
                            textAlign = TextAlign.Center
                        )

                    )
                }
            }
        }
    }
}

private val emojis = listOf(

    "\ud83d\ude00", // Grinning Face
    "\ud83d\ude01", // Grinning Face With Smiling Eyes
    "\ud83d\ude02", // Face With Tears of Joy
    "\ud83d\ude03", // Smiling Face With Open Mouth
    "\ud83d\ude04", // Smiling Face With Open Mouth and Smiling Eyes
    "\ud83d\ude05", // Smiling Face With Open Mouth and Cold Sweat
    "\ud83d\ude06", // Smiling Face With Open Mouth and Tightly-Closed Eyes
    "\ud83d\ude09", // Winking Face
    "\ud83d\ude0a", // Smiling Face With Smiling Eyes
    "\ud83d\ude0b", // Face Savouring Delicious Food
    "\ud83d\ude0e", // Smiling Face With Sunglasses
    "\ud83d\ude0d", // Smiling Face With Heart-Shaped Eyes
    "\ud83d\ude18", // Face Throwing a Kiss
    "\ud83d\ude17", // Kissing Face
    "\ud83d\ude19", // Kissing Face With Smiling Eyes
    "\ud83d\ude1a", // Kissing Face With Closed Eyes
    "\u263a", // White Smiling Face
    "\ud83d\ude42", // Slightly Smiling Face
    "\ud83e\udd17", // Hugging Face
    "\ud83d\ude07", // Smiling Face With Halo
    "\ud83e\udd13", // Nerd Face
    "\ud83e\udd14", // Thinking Face
    "\ud83d\ude10", // Neutral Face
    "\ud83d\ude11", // Expressionless Face
    "\ud83d\ude36", // Face Without Mouth
    "\ud83d\ude44", // Face With Rolling Eyes
    "\ud83d\ude0f", // Smirking Face
    "\ud83d\ude23", // Persevering Face
    "\ud83d\ude25", // Disappointed but Relieved Face
    "\ud83d\ude2e", // Face With Open Mouth
    "\ud83e\udd10", // Zipper-Mouth Face
    "\ud83d\ude2f", // Hushed Face
    "\ud83d\ude2a", // Sleepy Face
    "\ud83d\ude2b", // Tired Face
    "\ud83d\ude34", // Sleeping Face
    "\ud83d\ude0c", // Relieved Face
    "\ud83d\ude1b", // Face With Stuck-Out Tongue
    "\ud83d\ude1c", // Face With Stuck-Out Tongue and Winking Eye
    "\ud83d\ude1d", // Face With Stuck-Out Tongue and Tightly-Closed Eyes
    "\ud83d\ude12", // Unamused Face
    "\ud83d\ude13", // Face With Cold Sweat
    "\ud83d\ude14", // Pensive Face
    "\ud83d\ude15", // Confused Face
    "\ud83d\ude43", // Upside-Down Face
    "\ud83e\udd11", // Money-Mouth Face
    "\ud83d\ude32", // Astonished Face
    "\ud83d\ude37", // Face With Medical Mask
    "\ud83e\udd12", // Face With Thermometer
    "\ud83e\udd15", // Face With Head-Bandage
    "\u2639", // White Frowning Face
    "\ud83d\ude41", // Slightly Frowning Face
    "\ud83d\ude16", // Confounded Face
    "\ud83d\ude1e", // Disappointed Face
    "\ud83d\ude1f", // Worried Face
    "\ud83d\ude24", // Face With Look of Triumph
    "\ud83d\ude22", // Crying Face
    "\ud83d\ude2d", // Loudly Crying Face
    "\ud83d\ude26", // Frowning Face With Open Mouth
    "\ud83d\ude27", // Anguished Face
    "\ud83d\ude28", // Fearful Face
    "\ud83d\ude29", // Weary Face
    "\ud83d\ude2c", // Grimacing Face
    "\ud83d\ude30", // Face With Open Mouth and Cold Sweat
    "\ud83d\ude31", // Face Screaming in Fear
    "\ud83d\ude33", // Flushed Face
    "\ud83d\ude35", // Dizzy Face
    "\ud83d\ude21", // Pouting Face
    "\ud83d\ude20", // Angry Face
    "\ud83d\ude08", // Smiling Face With Horns
    "\ud83d\udc7f", // Imp
    "\ud83d\udc79", // Japanese Ogre
    "\ud83d\udc7a", // Japanese Goblin
    "\ud83d\udc80", // Skull
    "\ud83d\udc7b", // Ghost
    "\ud83d\udc7d", // Extraterrestrial Alien
    "\ud83e\udd16", // Robot Face
    "\ud83d\udca9", // Pile of Poo
    "\ud83d\ude3a", // Smiling Cat Face With Open Mouth
    "\ud83d\ude38", // Grinning Cat Face With Smiling Eyes
    "\ud83d\ude39", // Cat Face With Tears of Joy
    "\ud83d\ude3b", // Smiling Cat Face With Heart-Shaped Eyes
    "\ud83d\ude3c", // Cat Face With Wry Smile
    "\ud83d\ude3d", // Kissing Cat Face With Closed Eyes
    "\ud83d\ude40", // Weary Cat Face
    "\ud83d\ude3f", // Crying Cat Face
    "\ud83d\ude3e", // Pouting Cat Face
    "\ud83d\udc66", // Boy
    "\ud83d\udc67", // Girl
    "\ud83d\udc68", // Man
    "\ud83d\udc69", // Woman
    "\ud83d\udc74", // Older Man
    "\ud83d\udc75", // Older Woman
    "\ud83d\udc76", // Baby
    "\ud83d\udc71", // Person With Blond Hair
    "\ud83d\udc6e", // Police Officer
    "\ud83d\udc72", // Man With Gua Pi Mao
    "\ud83d\udc73", // Man With Turban
    "\ud83d\udc77", // Construction Worker
    "\u26d1", // Helmet With White Cross
    "\ud83d\udc78", // Princess
    "\ud83d\udc82", // Guardsman
    "\ud83d\udd75", // Sleuth or Spy
    "\ud83c\udf85", // Father Christmas
    "\ud83d\udc70", // Bride With Veil
    "\ud83d\udc7c", // Baby Angel
    "\ud83d\udc86", // Face Massage
    "\ud83d\udc87", // Haircut
    "\ud83d\ude4d", // Person Frowning
    "\ud83d\ude4e", // Person With Pouting Face
    "\ud83d\ude45", // Face With No Good Gesture
    "\ud83d\ude46", // Face With OK Gesture
    "\ud83d\udc81", // Information Desk Person
    "\ud83d\ude4b", // Happy Person Raising One Hand
    "\ud83d\ude47", // Person Bowing Deeply
    "\ud83d\ude4c", // Person Raising Both Hands in Celebration
    "\ud83d\ude4f", // Person With Folded Hands
    "\ud83d\udde3", // Speaking Head in Silhouette
    "\ud83d\udc64", // Bust in Silhouette
    "\ud83d\udc65", // Busts in Silhouette
    "\ud83d\udeb6", // Pedestrian
    "\ud83c\udfc3", // Runner
    "\ud83d\udc6f", // Woman With Bunny Ears
    "\ud83d\udc83", // Dancer
    "\ud83d\udd74", // Man in Business Suit Levitating
    "\ud83d\udc6b", // Man and Woman Holding Hands
    "\ud83d\udc6c", // Two Men Holding Hands
    "\ud83d\udc6d", // Two Women Holding Hands
    "\ud83d\udc8f" // Kiss
)